package net.sunofbeach.blog.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import net.sunofbeach.blog.pojo.User;
import net.sunofbeach.blog.pojo.query.UserQuery;
import net.sunofbeach.blog.pojo.vo.UserVO;
import net.sunofbeach.blog.response.Result;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 * 服务类
 * </p>
 *
 * @author Bing
 * @since 2021-11-24
 */
public interface UserService extends IService<User> {


    /**
     * 初始化管理员
     *
     * @param user
     * @param request
     * @return
     */
    Result initManagerAccount(User user, HttpServletRequest request);

    /**
     * 创建图灵验证码
     *
     * @param response
     * @param captchaKey
     * @throws Exception
     */
    void createCaptcha(HttpServletResponse response, String captchaKey) throws Exception;

    /**
     * 发送邮件验证码
     * <p>
     * 使用场景： 注册、找回密码、修改邮箱（会输入新的密码）
     * 注册： 如果已经注册，提示 该邮箱已经注册；
     * 找回密码： 如果没有注册，提示 该邮箱未注册
     * 修改邮箱（新的邮箱）： 如果已经注册，提示 该邮箱已经被注册
     * 解决： 根据不类型的场景，执行对应的业务逻辑。
     *
     * @param request      校验IP
     * @param type         不同类型使用场景：注册、找回密码、修改邮箱
     * @param emailAddress 邮箱地址
     * @return
     */
    Result sendEmail(HttpServletRequest request, String type, String emailAddress);


    /**
     * 用户注册
     *
     * @param user        用户
     * @param emailCode   邮箱验证码
     * @param captchaCode 图灵验证码
     * @param captchaKey  图灵验证码key
     * @param request     用于传IP地址
     * @return
     */
    Result register(User user, String emailCode, String captchaCode, String captchaKey, HttpServletRequest request);

    /**
     * 用户登录
     *
     * @param captcha    图灵验证码
     * @param captchaKey 图灵key
     * @param user       用户
     * @param request
     * @param response
     * @return
     */
    Result doLogin(String captcha, String captchaKey, User user, HttpServletRequest request, HttpServletResponse response);

    /**
     * 检查登录状态
     * 本质，通过用户携带的token_key 检查用户是否有登录，如果登录，返回用户信息
     *
     * @return
     */
    User checkSobUser();

    /**
     * 获取作者信息
     *
     * @param userId
     * @return
     */
    Result getUserInfo(String userId);

    /**
     * 检查邮箱是否被注册/返回给前端
     *
     * @param email
     * @return
     */
    Result checkEmailToFront(String email);

    /**
     * 检查用户名是否被注册
     * 返回给前端
     *
     * @param username
     * @return
     */
    Result checkUsernameToFront(String username);

    /**
     * 更新用户信息
     *
     * @param request
     * @param user
     * @return
     */
    Result updateUserInfo(HttpServletRequest request, User user);

    /**
     * 删除用户
     * 需要管理员权限
     *
     * @param userId
     * @return
     */
    Result deleteUserById(String userId);


    /**
     * 用户修改密码、找回密码
     *
     * @param verifyCode
     * @param user
     * @return
     */
    Result updateUserPassword(String verifyCode, User user);

    /**
     * 用户更新邮箱
     *
     * @param email
     * @param verifyCode
     * @return
     */
    Result updateEmail(String email, String verifyCode);

    /**
     * 退出登录
     * 1、拿到 token_key
     * 2、删除redis里对应的token
     * 3、删除mysql里对应的 refreshToken
     * 4、删除cookie里的token_key
     *
     * @return
     */
    Result doLogout();


    /**
     * 条件分页查询用户列表
     * @param query
     * @return
     */
    IPage<UserVO> selectPage(Page<UserVO> pageParam, UserQuery query);

    /**
     * 通过Token获取用户信息
     * @return
     */
    Result parseToken();

    /**
     * 管理员重置用户密码
     *
     * @param password
     * @param userId
     * @return
     */
    Result resetPassword(String userId, String password);
}
